package com.robertux.leaderboard.util;

import java.util.Calendar;
import java.util.List;

import com.robertux.leaderboard.beans.entities.DetalleGrupoProducto;
import com.robertux.leaderboard.beans.entities.ExclusionCliente;
import com.robertux.leaderboard.beans.entities.GrupoProducto;
import com.robertux.leaderboard.beans.entities.Meta;
import com.robertux.leaderboard.beans.entities.external.Sucursal;

public class FarmaciaQueriesBuilder {
	
	public static StringBuilder construirQueryConsultaVentas(GrupoProducto gPrd, Meta meta, List<ExclusionCliente> exclusiones) {
		StringBuilder query = new StringBuilder("SELECT T1.Factura_Id AS \"FACTURA_ID\", T1.Factura_Numero AS \"FACTURA_NUMERO\", COUNT(T1.Articulo_Id) AS \"TOTAL_ARTICULOS\", ")
			.append("SUM(T1.TOTAL_CANTIDAD) AS \"TOTAL_CANTIDADES\", SUM(T1.TOTAL_PRECIO) AS \"TOTAL_PRECIO\" FROM (");
		
		query.append("SELECT fenc.Factura_Id, fenc.Factura_Numero, fdet.Articulo_Id, SUM(fdet.Detalle_Cantidad) AS \"TOTAL_CANTIDAD\", ");
		query.append("SUM((fdet.Detalle_Precio_Unitario - fdet.Detalle_Descuento_monto) * fdet.Detalle_Cantidad) AS \"TOTAL_PRECIO\" ");
		query.append("FROM dbo.Factura_Detalle_2 fdet ");
		query.append("INNER JOIN dbo.Factura_Encabezado_2 fenc ON fdet.Factura_Id = fenc.Factura_Id AND fenc.Suc_Id = fdet.Suc_Id AND fenc.Caja_Id = fdet.Caja_Id ");
		query.append("WHERE fenc.Vendedor_Id = ").append(meta.getUsuario().getVendedorId()).append(" ");
		query.append("AND fenc.Suc_Id = ").append(meta.getSucursalId()).append(" ");
		query.append("AND YEAR(fenc.Factura_Fecha) = YEAR(CURRENT_TIMESTAMP) AND MONTH(fenc.Factura_Fecha) = MONTH(CURRENT_TIMESTAMP) ");
		
		if(exclusiones.size() > 0) {
			query.append("AND fenc.Cliente_Id NOT IN (").append(construirListaExclusiones(exclusiones)).append(") ");
		}
		
		query.append("GROUP BY fenc.Factura_Id, fenc.Factura_Numero, fenc.Suc_Id, fenc.Vendedor_id, fenc.Factura_Fecha, fdet.Articulo_Id");
		
		query.append(") T1 WHERE (");
		query.append(construirCondicionProductoCantidad("T1", gPrd));
		query.append(") GROUP BY T1.Factura_Id, T1.Factura_Numero");
		
		return query;
	}
	
	public static StringBuilder construirQueryConsultaVentas(Calendar calEjecucion, Sucursal suc, List<ExclusionCliente> exclusiones) {
		StringBuilder query = new StringBuilder("SELECT T1.Factura_Id AS \"FACTURA_ID\", T1.Factura_Numero AS \"FACTURA_NUMERO\", COUNT(T1.Articulo_Id) AS \"TOTAL_ARTICULOS\", ")
			.append("SUM(T1.TOTAL_CANTIDAD) AS \"TOTAL_CANTIDADES\", SUM(T1.TOTAL_PRECIO) AS \"TOTAL_PRECIO\" FROM (");
		
		query.append("SELECT fenc.Factura_Id, fenc.Factura_Numero, fdet.Articulo_Id, SUM(fdet.Detalle_Cantidad) AS \"TOTAL_CANTIDAD\", ");
		query.append("SUM((fdet.Detalle_Precio_Unitario - fdet.Detalle_Descuento_monto) * fdet.Detalle_Cantidad) AS \"TOTAL_PRECIO\" ");
		query.append("FROM dbo.Factura_Detalle_2 fdet ");
		query.append("INNER JOIN dbo.Factura_Encabezado_2 fenc ON fdet.Factura_Id = fenc.Factura_Id AND fenc.Suc_Id = fdet.Suc_Id AND fenc.Caja_Id = fdet.Caja_Id ");
		query.append("WHERE fenc.Suc_Id = ").append(suc.getId()).append(" ");
		query.append("AND YEAR(fenc.Factura_Fecha) = ").append(String.valueOf(calEjecucion.get(Calendar.YEAR))).append(" ");
		query.append("AND MONTH(fenc.Factura_Fecha) = ").append(String.valueOf(calEjecucion.get(Calendar.MONTH)+1)).append(" ");
		query.append("AND DAY(fenc.Factura_Fecha) <= ").append(String.valueOf(calEjecucion.get(Calendar.DAY_OF_MONTH))).append(" ");
		
		if(exclusiones.size() > 0) {
			query.append("AND fenc.Cliente_Id NOT IN (").append(construirListaExclusiones(exclusiones)).append(") ");
		}
		
		query.append("GROUP BY fenc.Factura_Id, fenc.Factura_Numero, fenc.Suc_Id, fenc.Vendedor_id, fenc.Factura_Fecha, fdet.Articulo_Id");
		
		query.append(") T1 ");
		query.append("GROUP BY T1.Factura_Id, T1.Factura_Numero");
		
		return query;
	}
	
	public static StringBuilder construirQueryConsultaItemsVentas(Calendar calEjecucion, Meta meta, GrupoProducto gPrd, List<ExclusionCliente> exclusiones, boolean todosRequeridos) {
		StringBuilder query = new StringBuilder();
		
		query.append("SELECT T.* FROM (SELECT fenc.Factura_Id, fenc.Factura_Numero, fdet.Articulo_Id, SUM(fdet.Detalle_Cantidad) AS \"TOTAL_CANTIDAD\", ");
		query.append("SUM((fdet.Detalle_Precio_Unitario - fdet.Detalle_Descuento_monto) * fdet.Detalle_Cantidad) AS \"TOTAL_PRECIO\" ");
		query.append("FROM dbo.Factura_Detalle_2 fdet ");
		query.append("INNER JOIN dbo.Factura_Encabezado_2 fenc ON fdet.Factura_Id = fenc.Factura_Id AND fenc.Suc_Id = fdet.Suc_Id AND fenc.Caja_Id = fdet.Caja_Id ");
		
		if(todosRequeridos && gPrd.getDetalleGrupoProductos().size() > 1) {
			query.append("INNER JOIN (SELECT fenc.Factura_Id, fenc.Factura_Numero, COUNT(fdet.Articulo_Id) AS \"TOTAL_ARTICULOS\" ");
			query.append("FROM dbo.Factura_Encabezado_2 fenc INNER JOIN dbo.Factura_Detalle_2 fdet ON fdet.Factura_Id = fenc.Factura_Id AND fenc.Suc_Id = fdet.Suc_Id AND fenc.Caja_Id = fdet.Caja_Id ");
			query.append("WHERE fenc.Vendedor_Id = ").append(meta.getUsuario().getVendedorId()).append(" ");
			query.append("AND fenc.Suc_Id = ").append(meta.getSucursalId()).append(" ");
			query.append("AND YEAR(fenc.Factura_Fecha) = ").append(String.valueOf(calEjecucion.get(Calendar.YEAR))).append(" ");
			query.append("AND MONTH(fenc.Factura_Fecha) = ").append(String.valueOf(calEjecucion.get(Calendar.MONTH)+1)).append(" ");
			
			if(exclusiones.size() > 0) {
				query.append("AND fenc.Cliente_Id NOT IN (").append(construirListaExclusiones(exclusiones)).append(") ");
			}
			query.append("AND fdet.Articulo_Id IN (").append(construirCondicionListaProductos(gPrd)).append(") ");
			query.append("GROUP BY fenc.Factura_Id, fenc.Factura_Numero HAVING COUNT(fdet.Articulo_Id) >= ").append(gPrd.getDetalleGrupoProductos().size()).append(" ");
			query.append(") T2 ON fenc.Factura_Id = T2.Factura_Id AND fenc.Factura_Numero = T2.Factura_Numero ");
		}
		
		
		query.append("WHERE fenc.Vendedor_Id = ").append(meta.getUsuario().getVendedorId()).append(" ");
		query.append("AND fenc.Suc_Id = ").append(meta.getSucursalId()).append(" ");
		query.append("AND YEAR(fenc.Factura_Fecha) = ").append(String.valueOf(calEjecucion.get(Calendar.YEAR))).append(" ");
		query.append("AND MONTH(fenc.Factura_Fecha) = ").append(String.valueOf(calEjecucion.get(Calendar.MONTH)+1)).append(" ");
		
		if(exclusiones.size() > 0) {
			query.append("AND fenc.Cliente_Id NOT IN (").append(construirListaExclusiones(exclusiones)).append(") ");
		}
		
		query.append(" GROUP BY fenc.Factura_Id, fenc.Factura_Numero, fenc.Suc_Id, fenc.Vendedor_id, fenc.Factura_Fecha, fdet.Articulo_Id) T ");
		query.append("WHERE ").append(construirCondicionProductoCantidad("T", gPrd)).append(" ");
		query.append("ORDER BY T.Factura_Id, T.Factura_Numero, T.Articulo_Id");
				
		return query;
	}
	
	public static StringBuilder construirCondicionListaProductos(GrupoProducto gPrd) {
		StringBuilder builder = new StringBuilder();
		for(DetalleGrupoProducto dGprd: gPrd.getDetalleGrupoProductos()) {
			if(builder.toString().trim().length() > 0) {
				builder.append(", ");
			}
			builder.append("'").append(dGprd.getProductoId()).append("'");
		}
		return builder;
	}
	
	public static StringBuilder construirCondicionProductoCantidad(String prefijo, GrupoProducto gPrd) {
		StringBuilder condicion = new StringBuilder();
		if(prefijo.trim().length() > 0) {
			prefijo += ".";
		}
		for(int i=0; i<gPrd.getDetalleGrupoProductos().size(); i++) {
			DetalleGrupoProducto det = gPrd.getDetalleGrupoProductos().get(i);
			if(i > 0) {
				condicion.append(" OR ");
			}
			condicion.append("(").append(prefijo).append("Articulo_Id = '").append(det.getProductoId()).append("'");
			condicion.append(" AND ABS(").append(prefijo).append("TOTAL_CANTIDAD) >= ").append(det.getCantidad()).append(")");
		}
		return condicion;
	}
	
	public static StringBuilder construirListaExclusiones(List<ExclusionCliente> exclusiones) {
		StringBuilder condicion = new StringBuilder();
		for(ExclusionCliente exclusion: exclusiones) {
			if(condicion.length() > 0) condicion.append(", ");
			condicion.append(exclusion.getCodigoCliente());
		}
		
		return condicion;
	}
}
